#include "VSMorphTree.h"
#include "VSMorphMainFunction.h"
#include "VSMorphBaseFunction.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI(VSMorphTree,VSController)
static bool gs_bStreamRegistered_VSMorphTree= VSMorphTree::RegisterMainFactory();
bool VSMorphTree::ms_bRegisterMainFactory = false;
bool VSMorphTree::RegisterMainFactory()
{
	if (!ms_bRegisterMainFactory)
	{ 
		VSMain::AddInitialFuntion(VSMorphTree::InitialClassFactory); 
		ms_bRegisterMainFactory = true;
	} 
	return ms_bRegisterMainFactory;

}
bool VSMorphTree::InitialClassFactory()
{
	ms_ClassFactory.AddElement(ms_Type.GetName(),FactoryFunc);

	return 1;
}
VSObject * VSMorphTree::FactoryFunc()
{
	return VS_NEW VSMorphTree();

}
VSMorphTree::~VSMorphTree()
{
	for(unsigned int i = 0 ; i < m_pMorphFunctionArray.GetNum() ; i++)
	{
		VSMorphBaseFunction * pMorphFunction = m_pMorphFunctionArray[i];
		m_pMorphFunctionArray[i] = NULL;
		VSMAC_DELETE(pMorphFunction);
	}

	m_pMorphFunctionArray.Clear();
	m_pMorphMainFunction = NULL;
}
VSMorphTree::VSMorphTree()
{
	m_pMorphFunctionArray.Clear();
	m_pMorphMainFunction = NULL;

	m_pMorphMainFunction = VS_NEW VSMorphMainFunction(_T("MorphTree"),this);
	VSMAC_ASSERT(m_pMorphMainFunction);



}
void VSMorphTree::AddMorphFunction(VSMorphBaseFunction * pMorphFunction)
{
	if(pMorphFunction)
	{
		m_pMorphFunctionArray.AddElement(pMorphFunction);
	}
}
bool VSMorphTree::Register(VSStream & rStream)const
{
	if (rStream.IsObjectRegister(this))
	{
		return 1;
	}
	if(!VSController::Register(rStream))
		return 0;

	if(m_pMorphMainFunction)
		if(!m_pMorphMainFunction->Register(rStream))
			return 0;
	for(unsigned int i = 0 ; i < m_pMorphFunctionArray.GetNum() ; i++)
	{
		if(m_pMorphFunctionArray[i])
			if(!m_pMorphFunctionArray[i]->Register(rStream))
				return 0;
	}
	return 1;
}
unsigned int VSMorphTree::DiskUse()const
{
	unsigned int Used = VSController::DiskUse();


	Used +=sizeof(VSMorphMainFunction *);

	Used +=sizeof(VSMorphBaseFunction *) * m_pMorphFunctionArray.GetNum();
	Used +=sizeof(unsigned int);
	return Used;
}
bool VSMorphTree::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSController::Save(rStream,iSaveUse))
		return 0;



// 	VSMorphMainFunction * pMorphMainFunction = m_pMorphMainFunction;
// 	if(!rStream.Write(&pMorphMainFunction,sizeof(VSMorphMainFunction *)))
// 		return 0;
	if(!rStream.WriteObjectPtr(m_pMorphMainFunction))
		return 0;
	iSaveUse += sizeof(VSMorphMainFunction *);

	unsigned int uiFunctionNum = m_pMorphFunctionArray.GetNum();
	if(!rStream.Write(&uiFunctionNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	for(unsigned int i = 0 ; i < uiFunctionNum ; i++)
	{
// 		VSMorphBaseFunction * pMorphFunction = m_pMorphFunctionArray[i];
// 		if(!rStream.Write(&pMorphFunction,sizeof(VSMorphBaseFunction *)))
// 			return 0;
		if(!rStream.WriteObjectPtr(m_pMorphFunctionArray[i]))
			return 0;
		iSaveUse += sizeof(VSMorphBaseFunction *);
	}


	return 1;
}
bool VSMorphTree::Load(VSStream & rStream,unsigned int &iSaveUse)
{	
	if(!VSController::Load(rStream,iSaveUse))
		return 0;


// 	VSMorphMainFunction * pMorphMainFunction = NULL;
// 	if(!rStream.Read(&pMorphMainFunction,sizeof(VSMorphMainFunction *)))
// 		return 0;
// 	AddLink(pMorphMainFunction);
	if(!rStream.ReadObjectPtr(m_pMorphMainFunction))
		return 0;
	iSaveUse += sizeof(VSMorphMainFunction *);

	unsigned int uiFunctionNum = m_pMorphFunctionArray.GetNum();
	if(!rStream.Read(&uiFunctionNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	m_pMorphFunctionArray.SetBufferNum(uiFunctionNum);
	for(unsigned int i = 0 ; i < uiFunctionNum ; i++)
	{
// 		VSMorphBaseFunction * pMorphFunction = NULL;
// 		if(!rStream.Read(&pMorphFunction,sizeof(VSMorphBaseFunction *)))
// 			return 0;
// 		AddLink(pMorphFunction);
		if(!rStream.ReadObjectPtr(m_pMorphFunctionArray[i]))
			return 0;
		iSaveUse += sizeof(VSMorphBaseFunction *);
	}

	return 1;
}
bool VSMorphTree::Link(VSStream & rStream)
{
	if(!VSController::Link(rStream))
		return 0;



	//m_pMorphMainFunction = (VSMorphMainFunction *)rStream.GetMapValue(GetNextLink());
	rStream.LinkObjectPtr(m_pMorphMainFunction);
	for(unsigned int i = 0 ; i < m_pMorphFunctionArray.GetNum() ; i++)
	{
		//m_pMorphFunctionArray[i] = (VSMorphBaseFunction *)rStream.GetMapValue(GetNextLink());
		rStream.LinkObjectPtr(m_pMorphFunctionArray[i]);
	}
	return 1;

}
bool VSMorphTree::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VSMorphTree* Temp = DynamicCast<VSMorphTree>(pObject); 
	if(!Temp)
		return 0;
	if(VSController::Clone(pObject,uiType))
	{
		for(unsigned int i = 0 ; i < m_pMorphFunctionArray.GetNum() ; i++)
		{
			VSMorphBaseFunction * pMorphBaseFunction = m_pMorphFunctionArray[i];
			m_pMorphFunctionArray[i] = NULL;
			VSMAC_DELETE(pMorphBaseFunction);
		}
		m_pMorphFunctionArray.Clear();
		m_pMorphMainFunction = NULL;


		unsigned int uiMorphFuntionNum = Temp->m_pMorphFunctionArray.GetNum();
		m_pMorphFunctionArray.Clear();
		m_pMorphFunctionArray.SetBufferNum(uiMorphFuntionNum);

		VSMorphMainFunction * pMorphMainFunction = NULL;
		VSArray<VSPutNode *> OldLinkArray, NewLinkArray;

		for(unsigned int i = 0 ; i < uiMorphFuntionNum ;i++)
		{
			VSMorphBaseFunction * pTemp1  = Temp->m_pMorphFunctionArray[i];
			VSMorphBaseFunction * pTemp2 =(VSMorphBaseFunction *)VSObject::GetInstance((pTemp1)->GetType().GetName());
			pTemp2->Clone(pTemp1,uiType);
			m_pMorphFunctionArray[i] = pTemp2;	
			m_pMorphFunctionArray[i]->SetOwner(this);
			pMorphMainFunction = DynamicCast<VSMorphMainFunction>(pTemp2);
			if(pMorphMainFunction)
			{
				m_pMorphMainFunction = pMorphMainFunction;
			}
			pTemp1->AddAllPutNodeTo(OldLinkArray);
			pTemp2->AddAllPutNodeTo(NewLinkArray);
		}
		for(unsigned int i = 0 ; i < uiMorphFuntionNum ;i++)
		{
			if(!m_pMorphFunctionArray[i]->Link(OldLinkArray,NewLinkArray))
				return 0;
		}
		VSMAC_ASSERT(m_pMorphMainFunction);
		return 1;

	}
	else
	{
		return 0;
	}

}
void VSMorphTree::DeleteMorphFunction(VSMorphBaseFunction * pMorphFunction)
{
	if(pMorphFunction)
	{
		for (unsigned int i = 0 ; i < m_pMorphFunctionArray.GetNum() ; i++)
		{
			if(m_pMorphFunctionArray[i] == pMorphFunction)
			{
				m_pMorphFunctionArray.Erase(i);
				return ;
			}
		}

	}
}
bool VSMorphTree::UpdateEx(double dAppTime)
{
	if(!VSController::UpdateEx(dAppTime))
		return false;
	for(unsigned int i = 0 ; i < m_pMorphFunctionArray.GetNum() ; i++)
	{
		m_pMorphFunctionArray[i]->ClearFlag();
	}
	if(!m_pMorphMainFunction->Update(dAppTime))
		return false;
	return true;
}
bool VSMorphTree::SetObject(VSObject * pObject)
{
	VSMeshNode* Temp = DynamicCast<VSMeshNode>(pObject); 
	if(!Temp)
		return 0;
	m_pObject = pObject;
	return 1;
}
